package std

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"strings"
)

type allCountries struct {
	allCountries map[string]Countries
}

type Countries struct {
	Code     string `json:"code"`      //国家或地区代码，大写
	AreaCode string `json:"area_code"` //区号
	Name     string `json:"name"`      //名称
}

var countriesDefault *allCountries //line支持的国家或地区列表

func init() {
	countriesDefault = &allCountries{allCountries: make(map[string]Countries)}
	reader := bufio.NewReader(bytes.NewReader([]byte(countriesTxt)))
	for {
		line, _, err := reader.ReadLine()
		if err != nil {
			if err == io.EOF {
				break
			}
			continue
		}
		if len(line) <= 2 {
			continue
		}
		split := strings.Split(string(line), "\t")
		if len(split) == 3 {
			countriesDefault.allCountries[strings.ToUpper(deleteAllSpace(split[0]))] = Countries{
				Code:     strings.ToUpper(deleteAllSpace(split[0])),
				AreaCode: deleteAllSpace(split[1]),
				Name:     split[2],
			}
		}
	}
}

// GetInfo 获取指定国家或地区的信息
func (lc *allCountries) GetInfo(countryCode string) (Countries, error) {
	if v, ok := lc.allCountries[strings.ToUpper(countryCode)]; ok {
		return v, nil
	}
	return Countries{}, fmt.Errorf("不存在" + strings.ToUpper(countryCode))
}

// GetInfoByAreaCode 获取指定区号的国家信息
func (lc *allCountries) GetInfoByAreaCode(areaCode string) ([]Countries, error) {
	_areaCode := PhoneKeepNumbersOnly(areaCode)
	var result []Countries
	for _, v := range lc.allCountries {
		if PhoneKeepNumbersOnly(v.AreaCode) == _areaCode {
			result = append(result, v)
		}
	}
	if len(result) > 0 {
		return result, nil
	}
	return nil, fmt.Errorf("不存在" + strings.ToUpper(areaCode))
}

// GetAllInfo 获取全部国家或地区信息
func (lc *allCountries) GetAllInfo() []Countries {
	var result = make([]Countries, 0, 300)
	for _, v := range lc.allCountries {
		result = append(result, v)
	}
	return result
}

// RemoveAreaCode 根据国家或地区代码，移除号码前面的+号、区号、前缀0
// 如果记录中不存在该国家或地区代码，则不做任何修改。
func (lc *allCountries) RemoveAreaCode(phone string, countryCode string) string {
	info, err := lc.GetInfo(countryCode)
	if err != nil {
		return phone
	}
	fullPhone := AutoDelAreaCode(info.AreaCode, phone)
	if fullPhone == "" {
		return phone
	}
	return fullPhone
}

// AddAreaCode 给号码添加上+号和区号
// 如果记录中不存在该国家或地区代码，则不做任何修改。
func (lc *allCountries) AddAreaCode(phone string, countryCode string) string {
	info, err := lc.GetInfo(countryCode)
	if err != nil {
		return phone
	}
	fullPhone := AutoAddAreaCode(info.AreaCode, phone)
	if fullPhone == "" {
		return phone
	}
	return fullPhone
}

// GetCountryInfo 获取指定国家或地区的区号及名称-根据国家或地区代码
func GetCountryInfo(countryCode string) (Countries, error) {
	return countriesDefault.GetInfo(countryCode)
}

// GetCountryInfoByAreaCode 获取指定区号的国家信息
func GetCountryInfoByAreaCode(areaCode string) ([]Countries, error) {
	return countriesDefault.GetInfoByAreaCode(areaCode)
}

// AutoParseAreaCode 自动解析区号，返回国家信息。
// fullPhone 必须是带有区号的，前面要有+号
func AutoParseAreaCode(fullPhone string) ([]Countries, error) {
	if len(fullPhone) <= 6 || fullPhone[0] != '+' {
		return nil, fmt.Errorf("参数fullPhone不正确，前面必须有+号。")
	}
	_tempFullPhone := PhoneKeepNumbersOnly(fullPhone)
	for i := 5; i > 0; i-- {
		list, err := GetCountryInfoByAreaCode(_tempFullPhone[:i])
		if err == nil {
			return list, nil
		}
	}
	return nil, fmt.Errorf("未解析出国家信息")
}

// AddAreaCode 给号码添加上+号和区号
// 如果记录中不存在该国家或地区代码，则不做任何修改。
func AddAreaCode(countryCode string, phone string) string {
	return countriesDefault.AddAreaCode(phone, countryCode)
}

// RemoveAreaCode 根据国家或地区代码，移除号码前面的+号、区号、前缀0
// 如果记录中不存在该国家或地区代码，则不做任何修改。
func RemoveAreaCode(countryCode string, phone string) string {
	return countriesDefault.RemoveAreaCode(phone, countryCode)
}

// GetAllCountriesInfo 获取全部国家或地区信息
func GetAllCountriesInfo() []Countries {
	return countriesDefault.GetAllInfo()
}
